import java.util.HashMap;
import java.util.Set;

import org.jgrapht.graph.DefaultWeightedEdge;
import org.jgrapht.graph.SimpleWeightedGraph;

/*******************************************************************************************************/
/*
* Description: This class camputes the new weight of the network edges.
* The weight is a weight combination of the GO similarity between the edges
* and the initial confidence of the edge.
* @author liat
*
/******************************************************************************************************/

public class WeightFunction {
	
	AnnotationsManager _annotData;
	HashMap<String, Gene> _geneMap;
	
	/**
	* The new weight function constructor.
	* @param geneMap - maps between a string to its matching gene.
	*/
	public WeightFunction(HashMap<String, Gene> geneMap, AnnotationsManager annotData) {
		_annotData = annotData;
		_geneMap = geneMap;
	}
	
	
	/**
	 * Alters the edge weights according to the new weight function.
	 * @param net the network to change its weight.
	 * @param alpha the weighting given to each method.
	 */
	public void alterNetWeight(SimpleWeightedGraph<String, DefaultWeightedEdge> net, double alpha) {
		Set<DefaultWeightedEdge> edges = net.edgeSet();
		double newWeight;
		Gene gene1, gene2;
		double weight;
		for (DefaultWeightedEdge edge: edges) {
			gene1 = _geneMap.get(net.getEdgeSource(edge));
			gene2 = _geneMap.get(net.getEdgeTarget(edge));
			weight = net.getEdgeWeight(edge);
			newWeight = calcEdgeWeight(alpha, gene1, gene2, weight);
			net.setEdgeWeight(edge, newWeight);
		}
	}
	
	
	
	/**
	* Calculates the new weight of the given edge.
	* gene1, gene2 and prob are the data of the edge.
	* @param alpha - the relative weight given to the
    * GO annotations similarity compared to the confidence
	* of the edge in the new weight function.
	*/
	public double calcEdgeWeight(double alpha, Gene gene1, Gene gene2, double prob) {		
		double annotSimilarity = _annotData.getAnnotSimilarity(gene1, gene2);
		if (annotSimilarity == 0) {
			return prob;
		}
		double newWeight = alpha * annotSimilarity + (1-alpha) * prob;
		return newWeight;
	}
	
	/*
	public static void main(String[] args) {
		String netFileName = "test2.sif";
		HashMap<String, Gene> geneMap = new HashMap<String, Gene>();
		SimpleWeightedGraph<String, DefaultWeightedEdge> net = 
			PPIFactory.generate(geneMap, netFileName);
		AnnotationsManager a = new AnnotationsManager();
		int annotatedGenesInGenome = a.load("./data/gene_ontology_edit.obo", "./data/gene_assoc_human.txt", geneMap);
		// Build genes map - consider moving to class / function.
		// TEMP TODO consider loading annotations at this stage.
		WeightFunction func = new WeightFunction(geneMap, a);
		func.alterNetWeight(net, 0.5);
		Set<DefaultWeightedEdge> edges = net.edgeSet();
		for (DefaultWeightedEdge edge: edges) {
			System.out.println(net.getEdgeSource(edge)+"\t"+net.getEdgeTarget(edge)+"\t"+net.getEdgeWeight(edge)+"\n");
		}
		System.out.println(net.toString());
	}
	*/
	
}
